## Задача 1. 

Объявите дескриптор данных `FloatValue`, который бы устанавливал и возвращал вещественные значения. 

При записи вещественного числа должна выполняться проверка на вещественный тип данных. 

Если проверка не проходит, то генерировать исключение командой:
```python
raise TypeError("Присваивать можно только вещественный тип данных.")
```
Объявите класс `Cell`, в котором создается объект value дескриптора `FloatValue`. 

А объекты класса `Cell` должны создаваться командой:
```python
cell = Cell(начальное значение ячейки)
```
Объявите класс `TableSheet`, с помощью которого создается таблица из N строк и M столбцов следующим образом:
```python
table = TableSheet(N, M)
```
Каждая ячейка этой таблицы должна быть представлена объектом класса `Cell`, работать с вещественными числами через объект
```python
value (начальное значение должно быть 0.0).
```
В каждом объекте класса `TableSheet` должен формироваться локальный атрибут:

> `cells` - список (вложенный) размером N x M, содержащий ячейки таблицы (объекты класса `Cell`).

С помощью метода `create_cells(n)` cоздайтся объект table класса `TableSheet`,
в ячейки которой который записываются числа от 1.0 до 15.0 

* Создайте таблицу размером  `N = 5, M = 3`.

* Запишите в эту таблицу числа от 1.0 до 15.0 (по порядку).

### Допишите программу
```python
class FloatValue:

    # def __init__(self):
    #   ....

    def __set_name__(self, owner, name):
        ...

    def __get__(self, instance, owner):
        ...

    def __set__(self, instance, value):
        if ... :
            raise TypeError(
                "Присваивать можно только вещественный тип данных.")
        ...


class Cell:
    value = FloatValue()
    def __init__(self, val=0.0):
        ...


class TableSheet:

    def __init__(self, N, M):
        self.cells = ...

    def create_cells(self, n):
      ...

table = TableSheet(5, 3)
table.create_cells(15)

```

Реализуйте вывод в консоль 
методом 
table.print()

```
Данные таблицы:
--------------------
01.0 | 02.0 | 03.0 | 
04.0 | 05.0 | 06.0 | 
07.0 | 08.0 | 09.0 | 
10.0 | 11.0 | 12.0 | 
13.0 | 14.0 | 15.0 | 
--------------------
```



## Задача 2. Валидатор для регистрации
_(техническое задание)_


Объявите класс `ValidateString` для проверки корректности переданной строки.

Объекты этого класса создаются командой:

```python
validate = ValidateString(min_length=3, max_length=100)
```
где

`min_length` - минимальное число символов в строке;

` max_length` - максимальное число символов в строке.

В классе `ValidateString` должен быть реализован метод:

`validate(self, string)` - возвращает `True`, если `string` является строкой (тип `str`) и длина строки в пределах `[min_length; max_length]`. 

Иначе возвращается `False`.

Объявите дескриптор данных `StringValue` для работы со строками, объекты которого создаются командой:

```python
st = StringValue(validator=ValidateString(min_length, max_length))
```

При каждом присвоении значения объекту `st` должен вызываться валидатор (объект класса `ValidateString`) и с помощью метода `validate()` проверяться корректность присваиваемых данных. 

Если данные некорректны, то присвоение не выполняется (игнорируется).

Объявите класс `RegisterForm` с тремя объектами дескриптора `StringValue`:

```python
login = StringValue(...) - для ввода логина;
password = StringValue(...)  - для ввода пароля;
email = StringValue(...)  - для ввода Email.
```
Объекты класса `RegisterForm` создаются командой:
```python
form = RegisterForm(логин, пароль, email)
```

где `логин, пароль, email` - начальные значения логина, пароля и `Email`.
В классе `RegisterForm` также должны быть объявлены методы:

`get_fields()` - возвращает список из значений полей в порядке `[login, password, email]`;

`show()` - выводит в консоль многострочную строку в формате:

```html
<form>
Логин: <login>
Пароль: <password>
Email: <email>
</form>
```

Функционал частично реализован. Попробуйте дописать методы на основе ТЗ

```python
class ValidateString:

    def __init__(self, min_length=3, max_length=100):
       ...

    def validate(self, string):        
        return ...        


class StringValue:

    def __init__(self, validator):
        self.validator = validator

    def __set_name__(self, owner, name):
        self.name = "_" + name

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]
        
    def __set__ (self,instance, value):
        if self.validator.validate(value):
            ...      
            
class RegisterForm:
    login = StringValue(validator=ValidateString()) 
    password = StringValue(validator=ValidateString())  
    email = StringValue(validator=ValidateString())

    def __init__(self,login, password, email):
       ...
   
        
    def get_fields(self):
        return [...]
    
    def show(self):
        print(...)
```


_____

# Тест на прогу
_____


```python
assert hasattr(ValidateString, 'validate'), "в классе ValidateString отсутствует метод validate"

r = RegisterForm('11111', '1111111', '11111111')
assert hasattr(r,'login') and hasattr(r, 'password') and hasattr(r, 'email'), "в классе RegisterForm должны быть дескрипторы login, password, email"

assert hasattr(RegisterForm, 'show'), "в классе RegisterForm отсутствует метод show"

StringValue.__doc__

frm = RegisterForm("123", "2345", "sc_lib@list.ru")
assert frm.get_fields() == ["123", "2345", "sc_lib@list.ru"], "метод get_fields вернул неверные данные"

frm.login = "root"
assert frm.login == "root", "дескриптор login вернул неверные данные"

v = ValidateString(5, 10)
assert v.validate("hello"), "метод validate вернул неверное значение"
assert v.validate("hell") == False, "метод validate вернул неверное значение"
assert v.validate("hello world!") == False, "метод validate вернул неверное значение"


class A:
    st = StringValue(validator=ValidateString(3, 10))


a = A()
a.st = "hello"

assert a.st == "hello", "дескриптор StringValue вернул неверное значение"
a.st = "d"
assert a.st == "hello", "дескриптор StringValue сохранил строку длиной меньше min_length"
a.st = "dапарпаропропропропр"
assert a.st == "hello", "дескриптор StringValue сохранил строку длиной больше max_length"
a.st = "dапарпароп"
assert a.st == "dапарпароп", "дескриптор StringValue сохранил строку длиной больше max_length"

```